///////////////////////////////////////////////////////////////////////////////
// cvec.h
// Author: Nick Leaf
// Last Updated: 9/2009
//
// Description: A vector for Cartesian 3-space with built-in implementation
// for common operations, including conversion to spherical coordinates.
//
// NOTE: conversion to spherical treats the y-axis as the azimuthal axis,
// i.e. theta measures elevation in relation to the y-axis, and phi determines
// angle in the x-z plane.
///////////////////////////////////////////////////////////////////////////////

#ifndef CVEC_H
#define CVEC_H

#include <string>
#include <iostream>

class svec;

class cvec{
    public:
        // Constructors //
        cvec(float x=0.f, float y=0.f, float z=0.f);
        cvec(float *arr);

        // Accessors //
        float x() const;
        float y() const;
        float z() const;
        float *toArray() const;
        std::string toString() const;

        // Mutators //
        void x(float x);
        void y(float y);
        void z(float z);

        // Coordinate conversion //
        svec toSpherical() const;

        // Vector operations //
        float mag() const;
        float dot(cvec iv) const;
        cvec plus(cvec iv) const;
        cvec minus(cvec iv) const;
        cvec cross(cvec iv) const;
        cvec mulByScalar(float f) const;
        cvec divByScalar(float f) const;
        cvec norm() const;
        float angle(cvec iv) const;
        cvec cwDiv(cvec iv) const; //component-wise divide

        // Overloaded operators //
        //value access
        operator float* ();
        float &operator [] (int i);

        //vector-vector operations
        cvec  operator+ (cvec v) const;
        cvec  operator- (cvec v) const;
        float operator* (cvec v) const;

        //scalar multiplication and division
        friend cvec operator* (float f, cvec v);
        friend cvec operator* (cvec v, float f);
        cvec operator/ (float f) const;

        //I/O
        friend std::ostream& operator<< (std::ostream &out, const cvec &v);
        friend std::istream& operator>> (std::istream &in, cvec &v);

    private:
        float v[3];
};

#endif
